package gameEngine;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Observable;

import javax.swing.event.MouseInputAdapter;

import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UpdateManagerAdapter;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;

public class BoardView extends ViewSon {
	/**
	 * 
	 */
	private static final long serialVersionUID = -1847451324838281289L;
	final int EDGE_SIZE = 20;
	protected Square[] board = new Square[EDGE_SIZE * EDGE_SIZE];
	Board boarD = null;
	DOMImplementation impl;
	String svgNS;
	SVGDocument doc;
	SVGGraphics2D boardContainer;
	JSVGCanvas canvas;
	Element root;
	int squareSize;
	UpdateManager canvasUM;
	ArrayList<Square> pointers;
	ArrayList<Square> oldpointers;
	Square pointer;
	Square oldPointer;
	Piece currentPiece;
	Engine controller;

	public BoardView(Engine _controller) {
		super();
		this.controller = _controller;
		impl = SVGDOMImplementation.getDOMImplementation();
		svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
		doc = (SVGDocument) impl.createDocument(svgNS, "svg", null);
		boardContainer = new SVGGraphics2D(doc);
		this.controller = _controller;
		
		squareSize = Square.getDefaultSize();
		//boardContainer.setSVGCanvasSize(new Dimension(EDGE_SIZE*squareSize, EDGE_SIZE*squareSize));
		boardContainer.setSVGCanvasSize(new Dimension(420, 420));
		pointers = new ArrayList<Square>();
		oldpointers = new ArrayList<Square>();
		pointer = new Square();
		oldPointer = new Square();
		oldPointer.setLocation(0, 0);

		for(int i = 0; i<EDGE_SIZE * EDGE_SIZE;i++){
			int x , y;
			x = i % EDGE_SIZE;
			y = i / EDGE_SIZE;
			pointer.setLocation(x+(x*squareSize), y+(y*squareSize));
			System.out.println(i);
			boardContainer.setColor(Color.pink);
			boardContainer.fill(pointer);
			boardContainer.setColor(Color.black);
			boardContainer.draw(pointer);

			
		}

		root = doc.getDocumentElement(); 
		boardContainer.getRoot(root);

		canvas = new JSVGCanvas();
		
		canvas.setDoubleBuffered(true);
		canvas.setDoubleBufferedRendering(true);
		canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
		canvas.setSVGDocument(doc);
		canvas.addUpdateManagerListener(new UpdateManagerAdapter() {
			public void updateCompleted(UpdateManagerEvent e) {
				canvas.repaint();
			}
		});
		
		setMouseListeners();
		this.add(canvas);
		canvas.setSize(new Dimension(420, 420));
		canvas.setBounds(0, 0, 420, 420);
		canvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
			public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
				loadThread();
			}
		});
		
		
		
	}
	
	private void setMouseListeners() {
		canvas.addMouseListener(new MouseInputAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				super.mouseClicked(e);
				System.out.println("Mouse has been clicked");
				
				int x = e.getX();
				int y = e.getY();
				
				x = (x - x%(squareSize + (squareSize/20)))/ getBoard().getEdgeSize();
				y = (y - y%(squareSize + (squareSize/20)))/ getBoard().getEdgeSize();
				
				if(currentPiece != null) {
					getBoard().putPiece(x, y, currentPiece);
					for (int i = 0; i <= pointers.size(); i++) {
						boardContainer.setColor(controller.getCurrentPiece().get親().getColor());
						boardContainer.fill(pointers.get(i));
						boardContainer.setColor(Color.BLACK);
						boardContainer.draw(pointers.get(i));
						oldpointers.remove(i);
					}
				}
			}
			
			@Override
			public void mouseEntered(MouseEvent e) {
				super.mouseEntered(e);
				initShapes();
				System.out.println("Mouse Entered");
			}
		});
		canvas.addMouseMotionListener(new MouseInputAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				super.mouseMoved(e);
				System.out.println("Mouse passed here " + e.getX() + " " + e.getY());
				int x = e.getX();
				int y = e.getY();
				
				x = x - x%(squareSize + (squareSize/20));
				y = y - y%(squareSize + (squareSize/20));
				
				
				if(pointers.get(0).getX() == x && pointers.get(0).getY() == y) {
					System.out.println("Nothing to do");
				}
				else {
					System.out.println("Mouse passed here : " + x + " " + y);
					if(currentPiece != null) {
					for(int i = 0; i < currentPiece.getConfiguration().length; i++) {
						for(int j=0; j < currentPiece.getConfiguration()[i].length; j++) {
							pointers.get(i+j).setLocation(
									(x+currentPiece.getConfiguration()[i][j]*(squareSize + (squareSize/20))),
									(y+(i*EDGE_SIZE*(squareSize + (squareSize/20))))
							);
							if(getBoard().isCaseFree(x/getBoard().getEdgeSize(), y/getBoard().getEdgeSize())) {
								boardContainer.setColor(Color.pink);
								if(i+j < oldpointers.size()) {
									boardContainer.fill(oldpointers.get(i+j));
								}
								boardContainer.setColor(Color.black);
								if(i+j < oldpointers.size()) {
									boardContainer.draw(oldpointers.get(i+j));
								}
							}
							if(getBoard().isCaseFree(x/getBoard().getEdgeSize(), y/getBoard().getEdgeSize())) {
								boardContainer.setColor(controller.getCurrentPiece().get親().getColor());
							}
							else {
								boardContainer.setColor(Color.orange);
							}
							boardContainer.fill(pointers.get(i+j));
							
							boardContainer.setColor(Color.red);
							boardContainer.draw(pointers.get(i+j));
							
							if(i+j < oldpointers.size()) {
								oldpointers.get(i+j).setLocation(
									pointers.get(i+j).getLocation()
								);
							}
							else {
								Square tmp = new Square();
								tmp.setLocation(pointers.get(i+j).getLocation());
								oldpointers.add(tmp);
						
							}
							
						}
					}
					}
					boardContainer.getRoot(root);
				}
				/*
				if(pointer.getX() == x && pointer.getY() == y) {
					System.out.println("Nothing to do");
				}
				else {
					System.out.println("Mouse passed here " + x + " " + y);

					
					pointer.setLocation(x,y);
					boardContainer.setColor(Color.blue);
					boardContainer.fill(pointer);
					
					boardContainer.setColor(Color.red);
					boardContainer.draw(pointer);
					
					boardContainer.setColor(Color.pink);
					boardContainer.fill(oldPointer);
					
					boardContainer.setColor(Color.black);
					boardContainer.draw(oldPointer);
					oldPointer.setLocation(x,y);
					
					//root = doc.getDocumentElement();
					boardContainer.getRoot(root);
					//canvas.setSVGDocument(doc);
					//canvas.repaint();
					
				}
				*/
			}
		});
	}

	public void loadThread() {
		System.out.println("Update Manager loaded");
		
		canvasUM = canvas.getUpdateManager();
	}
	
	public void initShapes() {
		System.out.println("initShapes was called");
		if(controller == null) {
			System.out.println("controller est null dans BoardView comme Java");
		}
		currentPiece = controller.getCurrentPiece();
		System.out.println("currentPiece was initialized");
		if(currentPiece == null) {
			System.out.println("currentPiece est null comme Java");
			pointers.add(new Square());
		}
		else {
			System.out.println("currentPiece n'est pas null mais Java l'est bien");
			for(int i = 0; i < currentPiece.getSize(); i++) {
				pointers.add(new Square());
			}
		}
	}
	
	private Board getBoard(){
		return controller.getBoardGame().getBoard();
	}
	
	private void setBoard(){
		boarD = controller.getBoardGame().getBoard();
	}
	
	
	@Override
	public void update(Observable obs, Object obj) {
		if (boarD == null) {
	        // Debug message
			System.out.println("BoardView.update(): Board is null, getting board from Engine");
			setBoard();
			
			if (boarD == null){
		        // Debug message
				System.out.println("BoardView.update(): Board is null, Java est encore plus null");
			}
		}
		else if ((String)obj != "init"){
			/*
			for(int i = 0; i < getBoard().getEdgeSize(); i++) {
				if(getBoard().get()[i] != 0) {
					p.setLocation(getBoard().iterToCoord(i)[0],getBoard().iterToCoord(i)[1]);
					boardContainer.setColor(controller.getCurrentPlayer().getColor());
					boardContainer.fill(p);
					boardContainer.setColor(Color.BLACK);
					boardContainer.draw(p);
				}
			}
			boardContainer.getRoot(root);
			*/
		};
		
		
	}
}

